"""
CausalRelationProcessor 模块 - 因果关系处理器

处理和保存因果关系的工具类
"""

import os
import json
import re
from collections import defaultdict
from typing import List, Dict, Any
import logging
from dataclasses import asdict
from source.graph.casualGraph import CausalityEdge

# 配置日志
logging.basicConfig(
    level=logging.INFO, format="%(asctime)s - %(levelname)s - %(message)s"
)
logger = logging.getLogger(__name__)



def extract_service_name(pod_name):
    """
    从pod名称中提取服务名称
    规则：保留倒数第二个'-'前面的内容
    例如：frontend-f6b45fb8b-bv45g -> frontend
          product-catalog-854fbdd574-8dp9j -> product-catalog
    """
    # 使用正则表达式匹配倒数第二个'-'之前的内容
    match = re.match(r"(.*)-[^-]+-[^-]+$", pod_name)
    if match:
        return match.group(1)
    return pod_name  # 如果无法匹配，则返回原始名称


class CausalRelationProcessor:
    """因果关系处理器"""

    def __init__(self, save_dir: str):
        """
        初始化因果关系处理器
        Args:
            save_dir: 保存目录
        """
        self.save_dir = save_dir
        # 修改数据结构，直接存储完整的边信息
        self.relations = defaultdict(list)
        self.pod_to_service_map = {}

    def process_edges(self, edges: List[CausalityEdge], method: str) -> None:
        """
        处理因果边
        Args:
            edges: 因果边列表
            method: 分析方法（'pcmci'或'direct'等）
        """
        if not edges:
            return

        # 更新 pod 到 service 的映射
        for edge in edges:
            if edge.cause_pod not in self.pod_to_service_map and "-" in edge.cause_pod:
                self.pod_to_service_map[edge.cause_pod] = extract_service_name(edge.cause_pod)
            if edge.effect_pod not in self.pod_to_service_map and "-" in edge.effect_pod:
                self.pod_to_service_map[edge.effect_pod] = extract_service_name(edge.effect_pod)

        # 直接存储边
        self.relations[method].extend(edges)

    def save_relations(self) -> None:
        """保存所有因果关系"""
        for method, edges in self.relations.items():
            if edges:  # 只保存非空的关系
                filename = f"{method}_causal_relations.json"
                self._save_to_file(edges, filename)

    def _save_to_file(self, edges: List[CausalityEdge], filename: str) -> None:
        """
        保存关系到文件
        Args:
            edges: 因果边列表
            filename: 文件名
        """
        # 按服务分组的关系
        service_relations: Dict[str, Dict[str, List[Dict[str, Any]]]] = {}

        for edge in edges:
            # 获取源服务和目标服务名称
            cause_cmdb_id = edge.cause_pod
            cause_service = self.pod_to_service_map.get(edge.cause_pod, edge.cause_pod)
            effect_service = self.pod_to_service_map.get(edge.effect_pod, edge.effect_pod)

            # 初始化服务的数据结构
            if cause_cmdb_id not in service_relations:
                service_relations[cause_cmdb_id] = {
                    "entity_type": edge.from_entity_type,  # 添加源实体类型
                    "OpenTelemetry": {}
                }
            if edge.cause_metric not in service_relations[cause_cmdb_id]["OpenTelemetry"]:
                service_relations[cause_cmdb_id]["OpenTelemetry"][edge.cause_metric] = []

            # 构建详细的效果信息
            effect_info = {
                "service": effect_service,
                "cmdb_id": edge.effect_pod,
                "entity_type": edge.to_entity_type,  # 添加目标实体类型
                "metric": edge.effect_metric,
                "strength": edge.strength,
                "p_value": edge.p_value,  # 添加p值
                "time_lag": edge.time_lag,
                "method": edge.method
            }

            service_relations[cause_cmdb_id]["OpenTelemetry"][edge.cause_metric].append(effect_info)

        output_path = os.path.join(self.save_dir, "casual", filename)
        os.makedirs(os.path.dirname(output_path), exist_ok=True)

        with open(output_path, "w", encoding='utf-8') as f:
            json.dump(service_relations, f, indent=4, ensure_ascii=False)

        logger.info(f"因果关系已保存到: {output_path}")
